package com.fsnbigdata.service.impl;
import com.fsnbigdata.domain.dto.NamingPair;
import com.fsnbigdata.repository.EcosystemImageRepository;
import com.fsnbigdata.service.api.EcosystemService;
import com.fsnbigdata.util.ObjectNull;
import com.fsnbigdata.vo.NewClass;
import com.querydsl.core.types.Predicate;
import org.apache.commons.lang3.StringUtils;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.roo.addon.layers.service.annotations.RooServiceImpl;
import com.fsnbigdata.domain.Ecosystem;
import com.fsnbigdata.repository.EcosystemRepository;
import io.springlets.data.domain.GlobalSearch;

import java.util.ArrayList;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Path;
import javax.persistence.criteria.Root;

/**
 * = EcosystemServiceImpl
 *
 * TODO Auto-generated class documentation
 *
 */
@RooServiceImpl(service = EcosystemService.class)
@Service
@Transactional(readOnly = true)
public class EcosystemServiceImpl implements EcosystemService {

    /**
     * TODO Auto-generated attribute documentation
     *
     */
    private EcosystemRepository ecosystemRepository;

    /**
     * TODO Auto-generated attribute documentation
     *
     */
    private EcosystemImageRepository ecosystemImageRepository;

    /**
     * TODO Auto-generated constructor documentation
     *
     * @param ecosystemRepository
     */
    @Autowired
    public EcosystemServiceImpl(EcosystemRepository ecosystemRepository, EcosystemImageRepository ecosystemImageRepository) {
        this.ecosystemRepository = ecosystemRepository;
        this.ecosystemImageRepository = ecosystemImageRepository;
    }


    public EcosystemImageRepository getEcosystemImageRepository() {
        return ecosystemImageRepository;
    }

    public void setEcosystemImageRepository(EcosystemImageRepository ecosystemImageRepository) {
        this.ecosystemImageRepository = ecosystemImageRepository;
    }

    /**
     * TODO Auto-generated method documentation
     *
     * @return EcosystemRepository
     */
    public EcosystemRepository getEcosystemRepository() {
        return ecosystemRepository;
    }

    /**
     * TODO Auto-generated method documentation
     *
     * @param ecosystemRepository
     */
    public void setEcosystemRepository(EcosystemRepository ecosystemRepository) {
        this.ecosystemRepository = ecosystemRepository;
    }

    /**
     * TODO Auto-generated method documentation
     *
     * @param ecosystem
     */
    @Transactional
    public void delete(Ecosystem ecosystem) {
        getEcosystemRepository().delete(ecosystem);
    }

    /**
     * TODO Auto-generated method documentation
     *
     * @param entities
     * @return List
     */
    @Transactional
    public List<Ecosystem> save(Iterable<Ecosystem> entities) {
        return getEcosystemRepository().save(entities);
    }

    /**
     * TODO Auto-generated method documentation
     *
     * @param ids
     */
    @Transactional
    public void delete(Iterable<Long> ids) {
        List<Ecosystem> toDelete = getEcosystemRepository().findAll(ids);
        getEcosystemRepository().deleteInBatch(toDelete);
    }

    /**
     * TODO Auto-generated method documentation
     *
     * @param entity
     * @return Ecosystem
     */
    @Transactional
    public Ecosystem save(Ecosystem entity) {
        return getEcosystemRepository().save(entity);
    }

    /**
     * TODO Auto-generated method documentation
     *
     * @param id
     * @return Ecosystem
     */
    public Ecosystem findOne(Long id) {
        return getEcosystemRepository().findOne(id);
    }

    /**
     * TODO Auto-generated method documentation
     *
     * @param id
     * @return Ecosystem
     */
    public Ecosystem findOneForUpdate(Long id) {
        return getEcosystemRepository().findOneDetached(id);
    }

    @Override
    public Page<Ecosystem> search(Predicate predicate, Pageable pageable) {
        return getEcosystemRepository().findAll(predicate, pageable);
    }

    /**
     * TODO Auto-generated method documentation
     *
     * @param ids
     * @return List
     */
    public List<Ecosystem> findAll(Iterable<Long> ids) {
        return getEcosystemRepository().findAll(ids);
    }

    /**
     * TODO Auto-generated method documentation
     *
     * @return List
     */
    public List<Ecosystem> findAll() {
        return getEcosystemRepository().findAll();
    }

    /**
     * TODO Auto-generated method documentation
     *
     * @return Long
     */
    public long count() {
        return getEcosystemRepository().count();
    }

    /**
     * TODO Auto-generated method documentation
     *
     * @param globalSearch
     * @param pageable
     * @return Page
     */
    public Page<Ecosystem> findAll(GlobalSearch globalSearch, Pageable pageable) {
        return getEcosystemRepository().findAll(globalSearch, pageable, null);
    }

    @Override
    public Page<Ecosystem> findAll(GlobalSearch globalSearch, Pageable pageable, String creator) {
        return getEcosystemRepository().findAll(globalSearch, pageable, creator);
    }

    /**
     * TODO Auto-generated method documentation
     *
     * @param ids
     * @param globalSearch
     * @param pageable
     * @return Page
     */
    public Page<Ecosystem> findAllByIdsIn(List<Long> ids, GlobalSearch globalSearch, Pageable pageable) {
        return getEcosystemRepository().findAllByIdsIn(ids, globalSearch, pageable);
    }

    @Override
    public List<NamingPair> findAllByInitial(String initial) {
        return getEcosystemRepository().findAllByInitial(initial);
    }

    @Override
    public List <List <Ecosystem>> findByType() {
        List<List <Ecosystem>> lists = new ArrayList <>(  );
        for(Integer i = 0;i<2;i++){
            List<Ecosystem> ecosystems = getEcosystemRepository().findByType( i );
            if(ecosystems!=null&&ecosystems.size()>4){
                lists.add( ecosystems.subList( 0,4 ) );
            }else {
                lists.add( ecosystems );
            }
        }
        return lists;
    }

    @Override
    public Page<Ecosystem> findByPageAndSize(Integer type,String creator,String create_date,String approver,String name, Pageable pageable) {
        Specification<Ecosystem> specification=new Specification<Ecosystem>() {
            @Override
            public javax.persistence.criteria.Predicate toPredicate(Root<Ecosystem> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {

                Path<String> _name=root.get("name");//关键字
                Path<String> _type=root.get("type");//类型
                Path<String> _creator=root.get("creator");//城建人
                Path<String> _createdate=root.get("createDate");//创建时间
                Path<String> _approver=root.get("approver");//采集地
                javax.persistence.criteria.Predicate _key = criteriaBuilder.like(_name,"%"+name+"%");
                javax.persistence.criteria.Predicate _creator_key = criteriaBuilder.like(_creator,"%"+creator+"%");
                javax.persistence.criteria.Predicate _createdate_key = criteriaBuilder.like(_createdate,"%"+_createdate+"%");
                javax.persistence.criteria.Predicate __approver_key = criteriaBuilder.like(_approver,"%"+approver+"%");
                javax.persistence.criteria.Predicate _type_key = criteriaBuilder.equal(_type,type);
                //当type=null时，只查关键字
                if (type==null){
                    return criteriaBuilder.and(_key);
                }

                if (StringUtils.isNotBlank(creator)||StringUtils.isNotBlank(create_date)||StringUtils.isNotBlank(approver)){

                    if (StringUtils.isNotBlank(creator)&&!creator.equals("")){
                        if(StringUtils.isNotBlank(create_date)&&!create_date.equals("")){
                            if(StringUtils.isNotBlank(approver)&&!approver.equals("")){
                                //判断采集地点是否为空
                                return criteriaBuilder.and(_key,_type_key,_creator_key,_createdate_key,__approver_key);
                            }
                            //判断时间和创建人都不为空
                            return criteriaBuilder.and(_key,_type_key,_creator_key,_createdate_key);
                        }
                        //判断创建人是否为空
                        return criteriaBuilder.and(_key,_type_key,_creator_key);
                    }
                    if (StringUtils.isNotBlank(create_date)&&!create_date.equals("")){
                        if(StringUtils.isNotBlank(creator)&&!creator.equals("")){
                            if(StringUtils.isNotBlank(approver)&&!approver.equals("")){
                                //判断采集地点是否为空
                                return criteriaBuilder.and(_key,_type_key,_creator_key,_createdate_key,__approver_key);
                            }
                            //判断时间和创建人都不为空
                            return criteriaBuilder.and(_key,_type_key,_creator_key,_createdate_key);
                        }
                        //判断创建时间是否为空
                        return criteriaBuilder.and(_key,_type_key,_createdate_key);
                    }
                    if (StringUtils.isNotBlank(approver)&&!approver.equals("")){
                        if(StringUtils.isNotBlank(creator)&&!creator.equals("")){
                            if(StringUtils.isNotBlank(create_date)&&!create_date.equals("")){
                                //判断采集地点、采集时间、采集人是否为空
                                return criteriaBuilder.and(_key,_type_key,_creator_key,_createdate_key,__approver_key);
                            }
                            //判断采集地点和采集都不为空
                            return criteriaBuilder.and(_key,_type_key,_creator_key,__approver_key);
                        }
                        //判断采集地点是否为空
                        return criteriaBuilder.and(_key,_type_key,__approver_key);
                   }
                }
                return criteriaBuilder.and(_key,_type_key);
            }
        };
        return getEcosystemRepository().findAll(specification,pageable);
    }

    @Override
    public List queryByKey(String name, String administrativeLocation,
                           String currentLevel, String createDate,
                           String administrativeDepartment, String type,
                           Pageable pageable1) {
        List list = new ArrayList(  );
        List<NewClass> ecosystems = new ArrayList <>(  );
        list.add( ecosystemRepository.queryCountByKey(name,administrativeLocation,currentLevel,createDate,administrativeDepartment,type) );

        for(Object o:ecosystemRepository.queryAllByKey(name,administrativeLocation,currentLevel,createDate,administrativeDepartment,type,pageable1)){
            Object[] objects = (Object[]) o;
            NewClass newClass = new NewClass();
            newClass.setId( ""+objects[0] );
            newClass.setName( ObjectNull.takeOutNull(objects[1] ));
            newClass.setLocation( ObjectNull.takeOutNull(objects[2] ));
            newClass.setDisturbances( ObjectNull.takeOutNull(objects[3] ));
            newClass.setNumber( ObjectNull.takeOutNull(objects[4] ));
            newClass.setCreator( ObjectNull.takeOutNull(objects[5] ));
            newClass.setNamed_info( ObjectNull.takeOutNull(objects[6] ));
            List<String> url = ecosystemImageRepository.getUrl( Long.parseLong( ""+objects[0] ) );
            newClass.setUrl( url.size()>0?url.get( 0 ):null );
            ecosystems.add( newClass );
        }
        list.add( ecosystems );
        return list;
    }

    /**
     * TODO Auto-generated method documentation
     *
     * @return Class
     */
    public Class<Ecosystem> getEntityType() {
        return Ecosystem.class;
    }

    /**
     * TODO Auto-generated method documentation
     *
     * @return Class
     */
    public Class<Long> getIdType() {
        return Long.class;
    }
}
